package br.com.sicoob.cedente.transacao;

import java.io.ByteArrayInputStream;
import java.io.IOException;

/**
 * Auxilia na leitura do stream. Foi necessaria a implementacao dessa classe
 * pois o codigo original escrito pela CTS trabalhava apenas com Strings o que
 * acarretava na excessao OutOfMemory
 * 
 * @author marcel.branco
 * 
 */
public class ByteArrayTokenizer {

	private ByteArrayInputStream payload;

	private char quebra;

	private int bytesLidosTotal = 0;

	private int bytesDisponiveis = 0;

	public ByteArrayTokenizer(byte[] payloadByte, char quebra) {
		this.payload = new ByteArrayInputStream(payloadByte);
		this.quebra = quebra;
		bytesDisponiveis = payload.available();
	}

	public String nextToken() {

		int bytesLidos = 0;
		byte testeUm = 0;

		while ((testeUm = (byte) payload.read()) != -1) {
			bytesLidosTotal++;
			bytesLidos++;

			if (((char) testeUm) == quebra) {

				try {
					payload.reset();
					byte[] ret = new byte[bytesLidos - 1];// -1 pra tirar a
					// quebra de linha

					payload.read(ret);
					
					char quebra = (char) payload.read();// so pra consumir
					
					// mesmo
					if (quebra != '\n') {
						throw new IllegalStateException(
								"tem que ser quebra de linha!");
					}
					String teste = null;
					if (java.nio.charset.Charset.isSupported("UTF-8")) {
						teste = new String(ret, "UTF-8");
					} else {
						teste = new String(ret);
					}

					payload.mark(getASerLido());
					return teste;
				} catch (IOException e) {
					e.printStackTrace();
				}
				return null;
			}
		}
		return null;
	}

	public int countTokens() {
		payload.mark(bytesDisponiveis);
		int total = 0;
		byte testeUm = 0;
		while ((testeUm = (byte) payload.read()) != -1) {
			char testa = (char) testeUm;
			if (testa == quebra) {
				total++;
			}
		}
		payload.reset();
		return total;
	}

	public boolean hasMoreTokens() {
		if (bytesLidosTotal < bytesDisponiveis) {
			return true;
		} else if (bytesLidosTotal == bytesDisponiveis) {
			return false;
		}
		return false;
	}

	private int getASerLido() {
		return bytesDisponiveis - bytesLidosTotal - 1;
	}
	

}
